package cn.sofwin.core.rbac.service;

import cn.sofwin.core.rbac.bean.LoginUser;
import cn.sofwin.core.utils.api.RequestResult;
import cn.sofwin.core.utils.api.StatusCode;
import cn.sofwin.core.utils.common.JsonUtils;
import cn.sofwin.core.utils.common.StringUtils;
import cn.sofwin.core.utils.security.Encodes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 授权服务
 */
@Service("authService")
public class AuthService {

    @Autowired
    RedisTemplate redisTemplate;

    private String tokenPrefix = "token_";

    /**
     * 生成Token
     * @return
     */
    public synchronized String generateToken(){
        String token = Encodes.nonceString(32);
        if(redisTemplate.opsForValue().get(tokenPrefix + token) == null){
            return token;
        }else{
            return generateToken();
        }
    }

    /**
     * 设置用户缓存
     * @param user
     * @return
     */
    public String setUserCache(LoginUser user) {
        String token = generateToken();
        redisTemplate.opsForValue().set(tokenPrefix + token, user);
        refreshToken(token);
        return token;
    }

    /**
     * 刷新缓存的过期时间
     * @param token
     */
    public void refreshToken(String token){
        if(redisTemplate.hasKey(tokenPrefix + token)){
            redisTemplate.expire(tokenPrefix + token, 30, TimeUnit.MINUTES);
        }
    }

    /**
     * 获取登录用户
     * @param request
     * @return
     */
    public LoginUser getLoginUser(HttpServletRequest request){
        LoginUser user = null;
        String token = getToken(request);
        if(StringUtils.isNotBlank(token)){
            refreshToken(token);
            user = (LoginUser) redisTemplate.opsForValue().get(tokenPrefix + token);
        }
        return user;
    }

    /**
     * 从HTTP请求头中获取token
     * @param request
     * @return
     */
    public String getToken(HttpServletRequest request){
        return request.getHeader("Authorization");
    }


    /**
     * 写入错误信息
     * @param response
     * @param httpStatus
     * @param statusCode
     */
    public void writeError(HttpServletResponse response, int httpStatus, StatusCode statusCode){
        response.setStatus(httpStatus);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=utf-8");
        RequestResult result = new RequestResult(statusCode);
        try {
            response.getWriter().write(JsonUtils.toJSON(result));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取客户端IP地址
     * @param request
     * @return
     */
    public String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip) || "null".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip) || "null".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip) || "null".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
